/*
 * Team Name: Focus
 * Team Members: Diana Groun, Edward Bassan
 * File Name: controller.h
 * Description: This file contains the prototype for a controller.
 */

#ifndef CONTROLLER_H_
#define CONTROLLER_H_

#include "memory.h"
#include "Register.h"
#include "RegisterFile.h"
#include "cpu.h"

//--Instruction Cycle--//
#define FETCH 0;
#define DECODE 1;
#define EVALUATE 2;
#define FETCH_OPERANDS 3;
#define EXECUTE 4;
#define STORE 5;
#define EXIT 6;
//--------------------//

//--- Bit Masks -----//
#define BITS_15_11_MASK 0xF800
#define BITS_2_0_MASK   0x0007
#define BITS_1_0_MASK   0x0003
#define BITS_6_1_MASK   0x007E
#define BITS_A_7_MASK   0x0780
#define BITS_6_3_MASK   0x0078
#define BITS_A_2_MASK	0x07FC
#define BITS_A_5_MASK	0x07D0
#define BITS_6_0_MASK   0x007F
#define BITS_8_0_MASK   0x01FF
#define BITS_10_0_MASK  0x07FF

#define BIT_0_MASK	  0x0001
#define BIT_6_MASK    0x0040
#define BIT_8_MASK    0x0100
#define BIT_10_MASK   0x0400
#define BIT_15_MASK   0x8000

//---- Opcode -------------------------------------------------------------------//

//Data Movement
#define LDI     0x1
#define LDA     0x2
#define LDB     0x3
#define LDW     0x4
#define MOV     0x4
#define STB     0x5
#define STW     0x6
#define PUSHB   0x7
#define POPB    0x7
#define PUSHW   0x7
#define POPW    0x7

//ALU OPERATIONS
#define	ADD		0x09
#define	SUB     0x09
#define	MUL		0x09
#define	DIV		0x09
#define	AND		0x09
#define	OR		0x09
#define	XOR		0x09
#define	NOT		0x09
#define	SHL		0x08
#define	SHR		0x0A

//Control Operations
#define	BRI		0x10
#define	BR		0x11
#define	BRIC	0x12
#define	BRIN	0x12
#define	BRIZ	0x12
#define	BRIO	0x12
#define	BRC		0x13
#define	BRN		0x13
#define	BRZ		0x13
#define	BRO		0x13
#define	JSR		0x14
#define	JSRC	0x15
#define	JSRN	0x15
#define	JSRZ	0x15
#define	JSRO	0x15
#define	TRAP	0x16
#define	RET		0x17
#define	RETI	0x17


//Register Port Numbers
#define PIT0  0x00
#define ADC   0x08
#define PIT1  0x10
#define SIO1  0x18
#define SIO2  0x20
#define PIO0  0x28
#define VID   0x30
#define KBD   0x38


//interrupt Vector Table
//Fixed address
#define  IVT    0x2100

//Supervisor Mode Instructions
#define   IN    0x18
#define   OUT   0x18

// Miscellaneous Operations
#define	HALT	0x1A
#define	NOP		0x00

//--------------------------------------------------------------------------------//

//---------------------------------Pseudo Code-----------------------------------//


// Defining a Controller
typedef struct controller {
        CpuPtr cpu;
        MemoryPtr memoryBlock;
        int opcode;
        int modifier;
        RegisterPtr address;

        int (*fetch)(struct controller*,int*);
        int (*decode)(struct controller*, int*);
        int (*evaluateAddress)(struct controller*, int*);
        int (*fetchOperands)(struct controller*);
        int (*execute)(struct controller*, int*);
        int (*storeAt)(struct controller*,int *);
        int (*switchCycle)(struct controller*, int*);
        int (*startCycle)(struct controller*);

} ControllerStr;

// Defining a Controller Pointer
typedef ControllerStr *ControllerPtr;

// Methods that will be used by the controller

ControllerPtr newController(void);
int fetch(ControllerPtr this,int* state);
int decode(ControllerPtr this, int* state);
int evaluateAddress(ControllerPtr this, int* state);
int fetchOperands(ControllerPtr this);
int execute(ControllerPtr this, int* state);
int storeAt(ControllerPtr this, int * state);
int startCycle(ControllerPtr this);
int switchCycle(ControllerPtr this, int* state);
unsigned short getImm9(unsigned short instructionReg);
unsigned short getImm7(unsigned short instructionReg);
unsigned short getImm11(unsigned short unstructionReg);
unsigned short Sext(unsigned short value);
int getRd(unsigned short instructionReg);
int getRa(unsigned short instructionReg);
int getRv(unsigned short instructionReg);
int getPort6(unsigned short instructionReg);
int getRs(unsigned short instructionReg);
unsigned short io(ControllerPtr this);
#endif /* CONTROLLER_H_ */
